package kgame5.k3d.util3d.reslib {
import kgame5.k3d.core.obj3d.info.material.MaterialInfo;
import kgame5.k3d.core.obj3d.node3d.animator.Animator3D;
import kgame5.k3d.core.parser.MD2Parser;
import kgame5.k3d.util3d.loader3d.Loader3DSkin;
import kgame5.kutil.KEvent;
import kgame5.kutil.T;

import flash.display.BitmapData;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import flash.utils.Dictionary;

/**
 * @author kangkai
 * 各种类型的资源都在这里,这个会自动加载，提取的时候用名字提取
 * md2 mtab skin.jpg
 * 
 * TODO 注意这个要改好，改成使用as3ds.Set的，保证没有重复的
 */
public class ResLib extends EventDispatcher{
	//全部加载完毕
	public static const 
		EVENTYTPE_ALL_COMPLETE:String="EVENTYTPE_ALL_COMPLETE",
		EVENTYTPE_ONE_COMPLETE:String="EVENTYTPE_ONE_COMPLETE";
	
	private  var dict:Dictionary;//dict[fileUrl]=res
	private  var idx:int;
	private  var aFileUrl:Array;//要加载的obj的文件地址,不能同时加载很多，否则解析的时候会堵塞的??
	
	private var l_skin:Loader3DSkin;
	private var l_x:URLLoader;//直接原因是加载xml用的,也可以加载txt
	private var l_md2:URLLoader;
	
	public function ResLib(){
		aFileUrl=new Array();
		dict=new Dictionary();
	}
	
	public function addUrl(sFileUrl:String):void{
		trace2("addUrl",sFileUrl);
		if(sFileUrl!=null){
			aFileUrl.push(sFileUrl);
		}
	}
	
	public function load():void{
		trace2("Lib3D.Start启动加载模型");

		idx=0;//idx开始是-1,因为loadNext是要加下一个的
		
		//下一步
		loadNext();
	}
	
	public function clear():void{
		dict=new Dictionary();
		aFileUrl=new Array();
		//idx=0;
	}
	
	//skin
	private function loadSkin(sSkinUrl:String):void{
		trace2("Lib3D.loadSkin",sSkinUrl);
		l_skin=new Loader3DSkin();
		l_skin.addEventListener(Loader3DSkin.EVENTTYPE_LOADOK, onLoadSkinOK);
		l_skin.Load(sSkinUrl);
	}
	private function onLoadSkinOK(e:KEvent):void{
		trace2("Lib3D--.onLoadSkinOK",aFileUrl[idx]);
		//trace2("加载皮肤到了，全替换皮肤");
		var bmd:BitmapData=e.info.bmd;
		
		var sFileUrl:String=aFileUrl[idx];
		dict[sFileUrl]=bmd;
		
		//下一步
		onLoadItemOK();
	}
	
	//==加载某种未知的文件
	private  function loadX(sFileUrl:String):void{
		trace2(this,"loadX",sFileUrl);
		l_x=new URLLoader();
		l_x.addEventListener(Event.COMPLETE, onLoadXOK);
		l_x.load(new URLRequest(sFileUrl));
	}
	private  function onLoadXOK(e:Event):void{
		trace2(this,"onLoadXOK",aFileUrl[idx]);
		
		var sFileUrl:String=aFileUrl[idx];
		
		dict[sFileUrl] = l_x.data;
		
		//下一步
		onLoadItemOK();
	}
	
	//加载md2文件
	private  function loadMD2(sFileUrl:String):void{
		trace2(this,"loadMD2",sFileUrl);
		l_md2=new URLLoader();
		l_md2.addEventListener(Event.COMPLETE, onLoadMD2OK);
		l_md2.dataFormat=URLLoaderDataFormat.BINARY;
		l_md2.load(new URLRequest(sFileUrl));
	}
	private  function onLoadMD2OK(e:Event):void{
		trace2(this,"onLoadMD2OK",aFileUrl[idx]);
		
		var sFileUrl:String=aFileUrl[idx];
		
		dict[sFileUrl] = l_md2.data;
		
		//下一步
		onLoadItemOK();
	}
	
	//加载下一个
	//注意，如果有.md2?223则(\.png)$ 是要失效的！
	private function loadNext():void{
		trace2(this,"loadNext");
		
		var sFileUrl:String=aFileUrl[idx];
			
		var re_png:RegExp=/(\.png)/i;
		var re_jpg:RegExp=/(\.jpg)/i;
		var re_md2:RegExp=/(\.md2)/i;

		if(re_jpg.test(sFileUrl)||re_png.test(sFileUrl)){//是jpg或png文件
			loadSkin(sFileUrl);
		}else if(re_md2.test(sFileUrl)){//是md2文件
			loadMD2(sFileUrl);
		}else{//未知类型文件
			loadX(sFileUrl);
		}
	}
	private function onLoadItemOK():void{
		
		this.dispatchEvent(new KEvent(EVENTYTPE_ONE_COMPLETE));
		
		if(idx==aFileUrl.length-1){//通知加载完毕
			this.dispatchEvent(new KEvent(EVENTYTPE_ALL_COMPLETE));
		}else{//还没加载完
			idx++;
			loadNext();
		}
	}
	
	//返回加载进度0~100
	public function getProgress():int{
		return (idx+1)/aFileUrl.length*100;
	}
	
	//根据名字取出内容
	 //* 1,var map_xml:XML=new XML(_lib3D_mapData.getData(NameX.getMapDataUrl(mapID)));
	//*  这个曾经花了很多时间做，原因是直接去的的这个不是xml，他只是个string,需要装换成xml
	public function getData(sName:String):Object{
		return dict[sName];
	}
	
	//!!严重注意，这个是clone后的data了
	public function getDataClone(sName:String):Object{
		var dd:Object=getData(sName);
		var ba:ByteArray=new ByteArray();
		ba.writeObject(dd);
		ba.position=0;
		return ba.readObject();
	}
	
	//取得一个Animator3D对象
	public function getAnimator3D(md2FileUrl:String,mtabFileUrl:String,skinFileUrl:String):Animator3D{
		var anim:Animator3D=null;
		
		//md2
		var md2Parser:MD2Parser=new MD2Parser(4);//注意这里的fps是无效的，就是随便写的一个
		md2Parser.parse(getDataClone(md2FileUrl) as ByteArray);
		anim=md2Parser.animator;
		
		//mtab
		if(getData(mtabFileUrl)==null){
			anim.setupActionTableXML(null);
		}else{
			anim.setupActionTableXML(new XML(getData(mtabFileUrl) as String));
		}
		
		//skin
		var mi:MaterialInfo=new MaterialInfo();
		mi.bmd=(getData(skinFileUrl) as BitmapData).clone();
		anim.setMaterialInfo(mi);
		
		return anim;
	}
	
	///////////////////调试信息//////////////////
	private function trace2(...args):void{
		T.p(args);
	}
}//end of class
}
